Skip to content

feat(agents): add Agents (experimental) to Grid API spec#430

Merged
k15z merged 13 commits intomainfrom
feat/agents-experimental
May 1, 2026
Merged

feat(agents): add Agents (experimental) to Grid API spec#430
k15z merged 13 commits intomainfrom
feat/agents-experimental

Conversation

@k15z
Copy link
Copy Markdown
Contributor

@k15z k15z commented May 1, 2026

Summary

Adds Agents (experimental) to the Grid API — a surface for connecting AI agents to Global Accounts with managed policy, approval flows, and delegated credentials.

New API surface

Agent Management (platform-scoped, BasicAuth)

  • POST /agents — create an agent with name, customer ID, and policy; returns agent + device code for installation
  • GET /agents — list agents with filters: customerId, isPaused, isConnected, date ranges, pagination
  • GET /agents/{agentId} — retrieve a single agent
  • PATCH /agents/{agentId} — update name or pause/unpause
  • DELETE /agents/{agentId} — permanently delete
  • PATCH /agents/{agentId}/policy — partial-update policy (permissions, execution mode, spending limits, account restrictions, approval thresholds)
  • POST /agents/{agentId}/device-codes — regenerate a device code (409 if agent already connected)
  • GET /agents/device-codes/{code}/status — poll for installation completion
  • POST /agents/device-codes/{code}/redeem — redeem device code for a Bearer access token (no auth)
  • GET /agents/approvals — platform-scoped list of pending AgentActions, with agentId/customerId filters
  • POST /agents/{agentId}/actions/{actionId}/approve — approve a pending agent action
  • POST /agents/{agentId}/actions/{actionId}/reject — reject a pending agent action (optional reason)

Agent Operations (agent-scoped, AgentAuth Bearer token)

  • GET /agents/me — agent reads its own profile and policy
  • GET /agents/me/actions / GET /agents/me/actions/{actionId} — poll approval status of submitted actions
  • GET /agents/me/internal-accounts — list customer's internal accounts (filtered by currency/type)
  • GET /agents/me/transactions / GET /agents/me/transactions/{id} — transaction history
  • POST /agents/me/quotes / GET /agents/me/quotes/{quoteId} — quote creation and retrieval
  • POST /agents/me/quotes/{quoteId}/execute — submit quote execution as an AgentAction
  • POST /agents/me/transfer-in / POST /agents/me/transfer-out — submit transfers as AgentActions
  • GET /agents/me/external-accounts / POST / GET /{id} / DELETE /{id} — manage external accounts

AgentAction approval model

All agent-initiated operations return an AgentAction (not a raw transaction or quote), giving the platform a consistent object to approve/reject with its own status lifecycle:

PENDING_APPROVAL → APPROVED | REJECTED | FAILED

The AgentAction embeds the full quote or transfer details, so approval UIs can render without a second API call. The FAILED state handles quote expiry — if approval takes too long and the underlying quote expires, the action transitions to FAILED rather than leaving it in limbo.

New webhook

AGENT_ACTION.PENDING_APPROVAL — fired when an agent submits an action requiring approval. Payload contains the full AgentAction so platforms can immediately send a push notification to the customer.

New schemas (24)

Agent management: Agent, AgentCreateRequest, AgentCreateResponse, AgentUpdateRequest, AgentListResponse, AgentPolicy, AgentPolicyUpdateRequest, AgentPermission, AgentExecutionMode, AgentSpendingLimits, AgentSpendingLimitsUpdate, AgentApprovalThresholds, AgentAccountRestrictions, AgentAccountRule, AgentUsage, AgentDeviceCode, AgentDeviceCodeStatusResponse, AgentDeviceCodeRedeemResponse

Approval flow: AgentAction, AgentActionStatus, AgentActionType, AgentActionListResponse, AgentTransferDetails, AgentActionRejectRequest

Webhook: AgentActionWebhook

Other spec changes

  • Transaction gains optional agentId field
  • AgentAuth security scheme added (type: http, scheme: bearer)
  • WebhookType enum extended with AGENT_ACTION.PENDING_APPROVAL
  • .stainless/stainless.ymlagent_access_token opt added (GRID_AGENT_ACCESS_TOKEN env var)

Docs (3 new pages)

  • mintlify/global-accounts/agents/overview.mdx — feature overview, system flow, design principles
  • mintlify/global-accounts/agents/policies-and-permissions.mdx — permissions reference, execution modes, spending limits, approval thresholds, full policy example
  • mintlify/global-accounts/agents/approvals-and-audit.mdx — approval lifecycle, outcomes, activity records, pause/revoke guidance

Test plan

  • make lint exits 0
  • make build regenerates bundle without errors
  • Stainless preview build passes (no SchemeNotFound errors)
  • Verify agent endpoints render in Mintlify preview (make mint)
  • Review AgentAction status lifecycle against server implementation
  • Confirm AgentAuth Bearer scheme aligns with server implementation
  • Confirm accessToken format/prefix (gat_...) matches server implementation
  • Confirm AGENT_ACTION.PENDING_APPROVAL webhook delivery matches server behavior

@vercel
Copy link
Copy Markdown

vercel Bot commented May 1, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
grid-flow-builder Ready Ready Preview, Comment May 1, 2026 5:49pm

Request Review

@mintlify
Copy link
Copy Markdown
Contributor

mintlify Bot commented May 1, 2026

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
Grid 🟢 Ready View Preview May 1, 2026, 5:05 AM

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 1, 2026

✱ Stainless preview builds

This PR will update the grid SDKs with the following commit messages.

kotlin

feat(agents): add Agents (experimental) to Grid API spec

openapi

feat(api): add agent management/operations endpoints, approval workflow, agentId to transactions

python

feat(api): add agents resource, device codes, agent transactions/quotes/accounts endpoints

typescript

feat(api): add agents resource, device codes, me namespace, agentId to transactions
⚠️ grid-openapi studio · code

Your SDK build had at least one "error" diagnostic.
generate ❗

⚠️ grid-kotlin studio · code

Your SDK build had at least one "error" diagnostic.
generate ❗build ✅lint ✅test ✅

⚠️ grid-python studio · code

Your SDK build had at least one "error" diagnostic.
generate ❗build ✅lint ✅test ✅

pip install https://pkg.stainless.com/s/grid-python/83b14c2b6495f749277def7550a53821df66546a/grid-0.0.1-py3-none-any.whl
⚠️ grid-typescript studio · code

Your SDK build had a failure in the lint CI job, which is a regression from the base state.
generate ❗build ✅lint ❗test ✅

npm install https://pkg.stainless.com/s/grid-typescript/4e14ef7e1df416ac9180ae56d64008e6af86d59d/dist.tar.gz

This comment is auto-generated by GitHub Actions and is automatically kept up to date as you push.
If you push custom code to the preview branch, re-run this workflow to update the comment.
Last updated: 2026-05-01 18:02:24 UTC

k15z added 8 commits May 1, 2026 07:09
Introduces two new tag groups:
- Agent Management: platform-scoped CRUD, policy, device codes, approvals (BasicAuth)
- Agent Operations: agent-scoped payments, quotes, transfers, external accounts (AgentAuth)

New schemas (18): Agent, AgentCreateRequest/Response, AgentUpdateRequest,
AgentListResponse, AgentPolicy, AgentPolicyUpdateRequest, AgentPermission,
AgentExecutionMode, AgentSpendingLimits/Update, AgentApprovalThresholds,
AgentAccountRestrictions/Rule, AgentUsage, AgentDeviceCode,
AgentDeviceCodeStatusResponse, AgentDeviceCodeRedeemResponse

New endpoints (19):
- POST/GET /agents, GET /agents/approvals
- GET/PATCH/DELETE /agents/{agentId}, PATCH /agents/{agentId}/policy
- POST /agents/{agentId}/device-codes (regenerate)
- GET /agents/device-codes/{code}/status, POST .../redeem
- POST /agents/{agentId}/transactions/{transactionId}/approve|reject
- GET /agents/me, GET/POST /agents/me/transactions, /quotes, /external-accounts
- POST /agents/me/transfer-in|out, /quotes/{quoteId}/execute

Also: adds agentId to Transaction schema; updates approvals-and-audit.mdx
and policies-and-permissions.mdx to match spec field names and shapes;
adds sidebar icons for both groups in style.css
…t Mintlify type rendering"

This reverts commit e768ff3.
…action fields

- Add agent_client_id/agent_client_secret opts to stainless.yml client_settings
  so Stainless can resolve the AgentAuth security scheme (fixes SchemeNotFound error)
- Fix approvals-and-audit.mdx to use correct OutgoingTransaction field names:
  sentAmount/receivedAmount (CurrencyAmount objects) instead of sendingAmount,
  and correct type discriminator value OUTGOING instead of OUTGOING_PAYMENT
Replace HTTP Basic (clientId + clientSecret) with a single Bearer access token
for agent authentication. Simpler for agent software to configure and store.

- AgentAuth security scheme: basic → bearer
- AgentDeviceCodeRedeemResponse: drop clientId/clientSecret, add accessToken
- stainless.yml: replace agent_client_id/secret opts with single agent_access_token
k15z added 2 commits May 1, 2026 07:09
All agent-initiated operations now return an AgentAction rather than a raw
Quote or Transaction, giving the platform a consistent object to approve/reject
with its own status lifecycle (PENDING_APPROVAL → APPROVED/REJECTED/FAILED).

- New schemas: AgentAction, AgentActionStatus, AgentActionType,
  AgentActionListResponse, AgentTransferDetails, AgentActionRejectRequest
- execute/transfer-out/transfer-in endpoints now return AgentAction
- GET /agents/approvals returns AgentActionListResponse (not TransactionListResponse)
- Approval endpoints moved from /agents/{id}/transactions/{id}/approve|reject
  to /agents/{id}/actions/{id}/approve|reject
- New agent-scoped: GET /agents/me/actions and GET /agents/me/actions/{actionId}
  for polling approval decisions
Maps all agent management endpoints explicitly to prevent stale guessed-config
errors after the approve/reject paths moved from /transactions/ to /actions/.
Update to reflect current API: AgentAction objects (not Transactions),
PENDING_APPROVAL status, AGENT_ACTION.PENDING_APPROVAL webhook flow,
new approve/reject endpoint paths, quote/transferDetails fields, and
FAILED state for expired quotes.
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 1, 2026

Greptile Summary

This PR adds the Agents (experimental) surface to the Grid API spec: 22 new endpoint paths, 24 new schemas, a device-code installation flow, AgentAuth bearer scheme, an AGENT_ACTION.PENDING_APPROVAL webhook, and accompanying Mintlify docs across 57 files.

  • P1 — Wrong approval URL in 3 operation descriptions: agents_me_transfer-in.yaml, agents_me_transfer-out.yaml, and agents_me_quotes_{quoteId}_execute.yaml all reference POST /agents/{agentId}/transactions/{transactionId}/approve, which does not exist; the correct endpoint is POST /agents/{agentId}/actions/{actionId}/approve.
  • P1 — Nonexistent COMPLETED status in docs: approvals-and-audit.mdx step 8 says the AgentAction transitions to APPROVED, then COMPLETED, but AgentActionStatus only defines PENDING_APPROVAL, APPROVED, REJECTED, and FAILED — integrators would poll for a terminal state that never arrives.

Confidence Score: 3/5

Two P1 documentation errors — a nonexistent approval endpoint URL and a nonexistent status value — need to be fixed before this ships to integrators.

Two P1 findings are present: a wrong endpoint URL propagated across three operation descriptions that would cause integrators to call a 404 path, and a COMPLETED status in the docs that doesn't exist in the spec's enum. These aren't runtime defects in the API itself but are specification-level errors that will directly mislead anyone building against this surface. Two P1s pull the score below the P1 ceiling of 4.

openapi/paths/agents/agents_me_transfer-in.yaml, agents_me_transfer-out.yaml, agents_me_quotes_{quoteId}_execute.yaml (wrong approval URL); mintlify/global-accounts/agents/approvals-and-audit.mdx (nonexistent COMPLETED status)

Important Files Changed

Filename Overview
openapi/paths/agents/agents_me_transfer-in.yaml New transfer-in endpoint for agents; description references a nonexistent approval endpoint URL (/agents/{agentId}/transactions/{transactionId}/approve instead of /agents/{agentId}/actions/{actionId}/approve)
openapi/paths/agents/agents_me_transfer-out.yaml New transfer-out endpoint for agents; same stale approval URL issue as transfer-in description
openapi/paths/agents/agents_me_quotes_{quoteId}_execute.yaml New execute-quote endpoint for agents; description references nonexistent /agents/{agentId}/transactions/{transactionId}/approve approval endpoint
mintlify/global-accounts/agents/approvals-and-audit.mdx Approval lifecycle docs updated with accurate webhook flow and field reference; step 8 incorrectly references a COMPLETED status that does not exist in AgentActionStatus
openapi/components/schemas/agents/AgentApprovalThresholds.yaml New schema for approval thresholds; currency described as required when amount is set but the constraint is not enforced in the schema
openapi/components/schemas/agents/AgentAction.yaml Core AgentAction schema with correct status references and embedded quote/transfer details for approval UI rendering; well structured
openapi/components/schemas/agents/AgentActionStatus.yaml Defines four terminal/non-terminal statuses: PENDING_APPROVAL, APPROVED, REJECTED, FAILED; note that COMPLETED (referenced in docs) is absent by design — APPROVED is the completion state
openapi/openapi.yaml Root spec additions: AgentAuth security scheme, tag descriptions, and 22 new path entries; literal paths (me, approvals, device-codes) correctly precede the {agentId} parameter path
openapi/webhooks/agent-action.yaml New webhook for AGENT_ACTION.PENDING_APPROVAL; includes full AgentAction example payload with webhook signature verification instructions
.stainless/stainless.yml Adds agents resource with all methods, subresources, and agent_access_token client setting for GRID_AGENT_ACCESS_TOKEN env var; clean structure
mintlify/global-accounts/agents/policies-and-permissions.mdx Updated permissions table and policy example to match actual enum values and correct field names; clean alignment with spec

Sequence Diagram

sequenceDiagram
    participant P as Platform Backend
    participant G as Grid API
    participant A as Agent Software
    participant C as Customer App

    P->>G: POST /agents (BasicAuth)
    G-->>P: AgentCreateResponse + DeviceCode

    A->>G: POST /agents/device-codes/{code}/redeem (no auth)
    G-->>A: accessToken (gat_...)

    P->>G: GET /agents/device-codes/{code}/status (BasicAuth)
    G-->>P: { redeemed: true }

    Note over A,G: Agent Operations (AgentAuth Bearer)
    A->>G: POST /agents/me/quotes
    G-->>A: Quote

    A->>G: POST /agents/me/quotes/{quoteId}/execute
    G-->>A: AgentAction { status: PENDING_APPROVAL }

    G-->>P: Webhook: AGENT_ACTION.PENDING_APPROVAL

    P->>C: Push notification
    C->>P: Approve / Reject
    P->>G: POST /agents/{agentId}/actions/{actionId}/approve (BasicAuth)
    G-->>P: AgentAction { status: APPROVED }

    Note over A,G: Agent polls for decision
    A->>G: GET /agents/me/actions/{actionId}
    G-->>A: AgentAction { status: APPROVED, transaction: {...} }
Loading

Fix All in Claude Code

Prompt To Fix All With AI
Fix the following 3 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 3
openapi/paths/agents/agents_me_transfer-in.yaml:8-10
**Wrong approval endpoint referenced in description**

The description points to `POST /agents/{agentId}/transactions/{transactionId}/approve`, but no such endpoint exists in this spec. The correct approval endpoint is `POST /agents/{agentId}/actions/{actionId}/approve`. This same stale URL appears in three places: here, `agents_me_transfer-out.yaml` (lines 8–10), and `agents_me_quotes_{quoteId}_execute.yaml` (line 17). Integrators following the embedded docs would call a 404-bound path and be unable to approve pending actions.

```suggestion
    If the agent's policy requires approval for this amount, the transaction will be
    created in a pending state and must be approved by the platform via
    `POST /agents/{agentId}/actions/{actionId}/approve`.
```

### Issue 2 of 3
mintlify/global-accounts/agents/approvals-and-audit.mdx:29
**`COMPLETED` status does not exist in the spec**

Step 8 describes the `AgentAction` transitioning to `APPROVED`, then `COMPLETED`. However, `AgentActionStatus.yaml` only defines four values: `PENDING_APPROVAL`, `APPROVED`, `REJECTED`, and `FAILED` — there is no `COMPLETED` terminal state. `APPROVED` is itself the completion state ("execution is in progress or completed" per the schema description). Documenting a nonexistent status here will cause integrators to poll for a terminal state that never arrives.

```suggestion
8. Grid executes the action and the `AgentAction` transitions to `APPROVED` — or `REJECTED` if declined. If the underlying quote expires before approval is granted, the action transitions to `FAILED` instead.
```

### Issue 3 of 3
openapi/components/schemas/agents/AgentApprovalThresholds.yaml:8-10
**Conditional `currency` requirement not enforced by schema**

The description says `currency` is "Required when amount is set," but the schema has no `required` array and no `if/then` constraint to enforce this. A client could send `{"amount": 100000}` without a `currency`, which would be semantically invalid — Grid couldn't know what denomination the threshold is in. Consider adding an `if/then` constraint:

```yaml
if:
  required: [amount]
  properties:
    amount:
      not:
        type: 'null'
then:
  required: [currency]
```

Reviews (1): Last reviewed commit: "Merge branch 'main' into feat/agents-exp..." | Re-trigger Greptile

Comment on lines +8 to +10
If the agent's policy requires approval for this amount, the transaction will be
created in a pending state and must be approved by the platform via
`POST /agents/{agentId}/transactions/{transactionId}/approve`.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Wrong approval endpoint referenced in description

The description points to POST /agents/{agentId}/transactions/{transactionId}/approve, but no such endpoint exists in this spec. The correct approval endpoint is POST /agents/{agentId}/actions/{actionId}/approve. This same stale URL appears in three places: here, agents_me_transfer-out.yaml (lines 8–10), and agents_me_quotes_{quoteId}_execute.yaml (line 17). Integrators following the embedded docs would call a 404-bound path and be unable to approve pending actions.

Suggested change
If the agent's policy requires approval for this amount, the transaction will be
created in a pending state and must be approved by the platform via
`POST /agents/{agentId}/transactions/{transactionId}/approve`.
If the agent's policy requires approval for this amount, the transaction will be
created in a pending state and must be approved by the platform via
`POST /agents/{agentId}/actions/{actionId}/approve`.
Prompt To Fix With AI
This is a comment left during a code review.
Path: openapi/paths/agents/agents_me_transfer-in.yaml
Line: 8-10

Comment:
**Wrong approval endpoint referenced in description**

The description points to `POST /agents/{agentId}/transactions/{transactionId}/approve`, but no such endpoint exists in this spec. The correct approval endpoint is `POST /agents/{agentId}/actions/{actionId}/approve`. This same stale URL appears in three places: here, `agents_me_transfer-out.yaml` (lines 8–10), and `agents_me_quotes_{quoteId}_execute.yaml` (line 17). Integrators following the embedded docs would call a 404-bound path and be unable to approve pending actions.

```suggestion
    If the agent's policy requires approval for this amount, the transaction will be
    created in a pending state and must be approved by the platform via
    `POST /agents/{agentId}/actions/{actionId}/approve`.
```

How can I resolve this? If you propose a fix, please make it concise.

Fix in Claude Code

5. Your app shows the customer the requested amount, accounts, and reason.
6. The customer approves or rejects from that trusted surface.
7. Your backend calls `POST /agents/{agentId}/actions/{actionId}/approve` or `.../reject`.
8. Grid executes the action and the `AgentAction` transitions to `APPROVED`, then `COMPLETED` — or `REJECTED` if declined.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 COMPLETED status does not exist in the spec

Step 8 describes the AgentAction transitioning to APPROVED, then COMPLETED. However, AgentActionStatus.yaml only defines four values: PENDING_APPROVAL, APPROVED, REJECTED, and FAILED — there is no COMPLETED terminal state. APPROVED is itself the completion state ("execution is in progress or completed" per the schema description). Documenting a nonexistent status here will cause integrators to poll for a terminal state that never arrives.

Suggested change
8. Grid executes the action and the `AgentAction` transitions to `APPROVED`, then `COMPLETED` — or `REJECTED` if declined.
8. Grid executes the action and the `AgentAction` transitions to `APPROVED` — or `REJECTED` if declined. If the underlying quote expires before approval is granted, the action transitions to `FAILED` instead.
Prompt To Fix With AI
This is a comment left during a code review.
Path: mintlify/global-accounts/agents/approvals-and-audit.mdx
Line: 29

Comment:
**`COMPLETED` status does not exist in the spec**

Step 8 describes the `AgentAction` transitioning to `APPROVED`, then `COMPLETED`. However, `AgentActionStatus.yaml` only defines four values: `PENDING_APPROVAL`, `APPROVED`, `REJECTED`, and `FAILED` — there is no `COMPLETED` terminal state. `APPROVED` is itself the completion state ("execution is in progress or completed" per the schema description). Documenting a nonexistent status here will cause integrators to poll for a terminal state that never arrives.

```suggestion
8. Grid executes the action and the `AgentAction` transitions to `APPROVED` — or `REJECTED` if declined. If the underlying quote expires before approval is granted, the action transitions to `FAILED` instead.
```

How can I resolve this? If you propose a fix, please make it concise.

Fix in Claude Code

Comment on lines +8 to +10
type: string
description: ISO 4217 currency code that the amount threshold is denominated in. Required when amount is set.
example: USD
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Conditional currency requirement not enforced by schema

The description says currency is "Required when amount is set," but the schema has no required array and no if/then constraint to enforce this. A client could send {"amount": 100000} without a currency, which would be semantically invalid — Grid couldn't know what denomination the threshold is in. Consider adding an if/then constraint:

if:
  required: [amount]
  properties:
    amount:
      not:
        type: 'null'
then:
  required: [currency]
Prompt To Fix With AI
This is a comment left during a code review.
Path: openapi/components/schemas/agents/AgentApprovalThresholds.yaml
Line: 8-10

Comment:
**Conditional `currency` requirement not enforced by schema**

The description says `currency` is "Required when amount is set," but the schema has no `required` array and no `if/then` constraint to enforce this. A client could send `{"amount": 100000}` without a `currency`, which would be semantically invalid — Grid couldn't know what denomination the threshold is in. Consider adding an `if/then` constraint:

```yaml
if:
  required: [amount]
  properties:
    amount:
      not:
        type: 'null'
then:
  required: [currency]
```

How can I resolve this? If you propose a fix, please make it concise.

Fix in Claude Code

@k15z k15z merged commit a67f681 into main May 1, 2026
8 of 9 checks passed
@k15z k15z deleted the feat/agents-experimental branch May 1, 2026 17:55
pengying pushed a commit that referenced this pull request May 1, 2026
…status (#433)

## Summary

- **Auth scheme**: Added `AgentAuth` to the global `security` array in
`openapi/openapi.yaml`. Per Stainless docs, the top-level security array
determines which schemes the SDK client supports — without it, the
Stainless `merge` step was failing, which is why the published docs at
grid.lightspark.com never reflected the agents endpoints after #430
merged.
- **Stale paths**: Three agent endpoint descriptions still referenced
the old `POST /agents/{agentId}/transactions/{transactionId}/approve`
path. Updated to `POST /agents/{agentId}/actions/{actionId}/approve`.
- **Phantom status**: `approvals-and-audit.mdx` step 8 documented a
`COMPLETED` terminal state that does not exist in `AgentActionStatus`.
`APPROVED` is the terminal success state. Removed to prevent integrators
from polling for a state that never arrives.

## Test plan

- [ ] Stainless `merge` check passes (unblocks published docs update)
- [ ] Verify agent endpoints appear in published sidebar after merge
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants